/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function (s) {

    if (!s || !s.length) {
        return 0
    }

    // 用于存放当遇到重复字符时，窗口左边界的下一个位置,使用数组比使用对象或map节约空间
    let nextLMap = new Array(128).fill(0)
    let l = 0
    let ans = 0
    for (let i = 0; i < s.length; i++) {
        l = Math.max(l, nextLMap[s.charCodeAt(i)] || 0)
        // 就是说，如果s[i]已经出现了一次，那么l将会移动到上一次出现位置 + 1
        // 如果没有出现，那么l就不会变
        nextLMap[s.charCodeAt(i)] = i + 1
        ans = Math.max(ans, i - l + 1)
    }
    return ans
}

let input = "abc-$abcbb"

console.log(lengthOfLongestSubstring(input))

//================v1要点总结===============
/**
 * 1. 参考题解，一个特别巧妙的思路，进行优化
 * 2. 数据结构采用Map或者对象时，占用空间比使用数组大
 * 3. 为什么长度使用128？因为题目中说到，s由英文字母、数字、符号和空格组成，这些所有的，ASCII码都未超过128（特殊字符除外，可用String.fromCharCode打印）
 */

